
#ifndef SX_MSS_REPLAY_EDIT_CONTROLLER_H
#define SX_MSS_REPLAY_EDIT_CONTROLLER_H

#include <sxMassSpringSimulationReplayController.h>
#include <sxFixedTimelineCurveController.h>
#include <sxMassSpringSimulationRecorder.h>
#include <sxStoredMesh_Archetype.h>
#include <sxMSS_PreviewRecorder.h>

using Sx::Multimedia::Interface::FixedTimelineCurveController;
using Sx::Simulation::Recording::MassSpringSimulationRecorder;

/* Recording Types */
using Sx::Physics::Archetypes::Objects::StoredMesh_Archetype;
using Sx::Simulation::Recording::MSS_PreviewRecorder;
using Sx::Simulation::Recording::MSS_PreviewRecording;

namespace Sx {
namespace Simulation {
namespace Interface {

class MSS_ReplayEditController : public MassSpringSimulationReplayController {
public:
	MSS_ReplayEditController(Viewport* viewport, 
		const std::shared_ptr<Canvas>& canvas, 
		const std::shared_ptr<ScenePickingController>& pickingController, 
		const std::shared_ptr<RendererImplementation>& cameraRenderer, 
		const std::shared_ptr<MassSpringSimulation>& simulation, 
		const std::shared_ptr<MassSpringSimulationRecording>& recording,
		const std::shared_ptr<MassSpringSimulationRecorder>& recorder,
		const std::shared_ptr<RendererImplementation>& previewMeshRenderer);

	virtual ~MSS_ReplayEditController();

	void update(float dt);
	void render() const;

	/*
	 * Apply an external force using the values provided by the curve editor.
	 */
	bool applyExternalForce(const std::shared_ptr<FixedTimelineCurveController>& curveEditor);

	/*
	 * Based on the end of the internal recording (contained within the
	 * recorder), generate a preview of the next n time-steps while saving
	 * every m_th frame as a preview;
	 */
	bool generateSimulationPreview(unsigned int n, unsigned int m);
	void clearSimluationPreview();

protected:
	std::shared_ptr<MassSpringSimulationRecorder> recorder;
	
	// Simulation Preview Recording 
	Util::ArrayList<StoredMesh_Archetype> previewMeshes;
	std::shared_ptr<MSS_PreviewRecording> previewRecording;
	std::shared_ptr<MSS_PreviewRecorder> previewRecorder;
	std::shared_ptr<RendererImplementation> previewMeshRenderer;

	// temp cache for the force curve..
	Util::ArrayList<Eigen::Vector3f> points;
	long forceStartIndex, forceEndIndex;

	void applyMeshForce();
	void removeMeshForce();
};

}

}

}

#endif
